gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/libsrc/ringlib/ringstr.cpp
/********************************************************************** // // // ########## ###### ######### # ###### # // ############# ########### ######### ######### ### // ######## # ### ## ############# ## ## ##### # #### // #### ## ## ### ### ### # # ##### ##### // # ### # # ## ## ## ## ### // ## ###### ## ## #### #### # # ## // ######### ### ## ### ####### ###### ## ## ### // ###### ## ###### ## ## #### # ## #### // ####### ## ###### ## ### ## ## ### ###### // ######### ## ###### ## ###### ### ## ### # ##### // ## ###### ####### ### #### ## ## ####### ######## ## #### // ## #### ### # ### ### ## ########## ###### ## #### // ## ## ## ######### #### # ## // # ### // ## // ### // ## // // // RingSDK类库 ringlib.lib //作者:临风 // //版本:1.0 // //声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到 // 你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在 // 修改的同时给作者一份同样的副本。 // 本类库不得用于任何商业用途,如确实需要,请与作者联系。 // //e-mail:ringphone@sina.com // //原文件名:ringstr.h // //说明: // 字符串操作类 ringStr 实现 // **********************************************************************/ #define MAKE_SELF_LIB #include "ringlib.h" void exwsprintf(LPSTR s,LPCTSTR format,...) { va_list ap; if(format) { va_start(ap, format); vsprintf(s,format,ap); va_end(ap); } } ringStr::ringStr(LPCTSTR str,DWORD size/*=0*/) { if(str) { m_len = (DWORD)lstrlen(str); if(m_len > size) if(m_len < RSTR_INIT) m_size = RSTR_INIT; else m_size = m_len + sizeof(TCHAR); else m_size = size; m_data = (LPTSTR)New(m_size * sizeof(TCHAR)); if(m_data) lstrcpy(m_data,str); else init(); } else { m_len = m_size = 0; m_data = NULL; } m_wData = NULL; } ringStr::ringStr(int size) { m_wData = NULL; memset(x,0,4); m_data = NULL; m_size = m_len = 0; if(size <= RSTR_PCNAME && size >= RSTR_WINPATH) LoadSpecial(size); else { if(size < 0) size = 0; m_size = size; m_len = 0; m_data = (LPTSTR)New(size * sizeof(TCHAR)); if(!m_data) init(); } } BOOL ringStr::LoadSpecial(int nFlag) { if(m_data && m_size < RSTR_STEP) m_data = (LPTSTR)Del(m_data); if(m_data == NULL) { m_data = (LPTSTR)New(RSTR_STEP * sizeof(TCHAR)); m_size = m_data?RSTR_STEP:0; } else Clear(); m_len = 0; if(m_data) { switch(nFlag) { case RSTR_WINPATH: m_len = GetWindowsDirectory(m_data,m_size); break; case RSTR_SYSPATH: m_len = GetSystemDirectory(m_data,m_size); break; case RSTR_TEMPPATH: m_len = GetTempPath(m_size,m_data) - 1; m_data[m_len] = 0; break; case RSTR_CURRPATH: { m_len = GetModuleFileName(GetInstance(),m_data,m_size); TCHAR c; for(int i=m_len-1;i>1;i--) { c = m_data[i]; m_data[i] = 0; m_len --; if(c == '\\') break; } break; } case RSTR_MYFILENAME: m_len = GetModuleFileName(GetInstance(),m_data,m_size); break; case RSTR_PCNAME: GetComputerName(m_data,&m_len); break; } } return (BOOL)m_len; } ringStr::ringStr(const ringStr& src) { m_wData = NULL; if(&src == this || src.m_data == NULL) { m_data = NULL; m_len = 0; m_size = 0; return; } else { m_data = (LPSTR)New(src.m_size); if(m_data) { lstrcpy(m_data,src.m_data); m_len = src.m_len; m_size = src.m_size; } } } ringStr::~ringStr() { Release(); } void ringStr::Release() { m_data = (LPSTR)Del(m_data); m_wData = (WCHAR*)Del(m_wData); m_len = m_size = 0; } void ringStr::Clear() { if(m_data) memset(m_data,0,m_size * sizeof(TCHAR)); m_len = 0; } void ringStr::init() { m_data = (LPTSTR)New(RSTR_INIT * sizeof(TCHAR)); if(m_data) { m_size = RSTR_INIT; m_len = 0; } else m_len = m_size = 0; } int ringStr::GetLength() { if(m_data) m_len = lstrlen(m_data); else m_len = 0; return m_len; } TCHAR& ringStr::operator [](int index) { if((DWORD)index < m_len) return m_data[index]; else { x[0] = '\0'; return x[0]; } } int ringStr::Load(UINT ident,HINSTANCE hInst) { if(m_data && m_size < RSTR_STEP) m_data = (LPTSTR)Del(m_data); if(m_data == NULL) { m_data = (LPTSTR)New(RSTR_MAX * sizeof(TCHAR)); m_size = RSTR_MAX; } else Clear(); m_len = LoadString(hInst,ident,m_data,m_size); return m_len; } int ringStr::printf(LPCTSTR format,...) { TCHAR s[RSTR_MAX]; va_list ap; if(format) { va_start(ap, format); _vsntprintf(s,RSTR_MAX-2,format,ap); //vsprintf(s, format, ap); va_end(ap); } m_len = lstrlen(s); Clear(); if(m_len < m_size) lstrcpy(m_data,s); else { Del(m_data); if(m_len < RSTR_STEP) m_size = RSTR_STEP; else m_size = RSTR_MAX; m_data = (LPTSTR)New(m_size * sizeof(TCHAR)); if(m_data) lstrcpy(m_data,s); else init(); } return m_len; } int ringStr::strcat(LPCTSTR format,...) { char s[RSTR_MAX]; va_list ap; if(format) { va_start(ap, format); _vsntprintf(s,RSTR_MAX-2,format,ap); //vsprintf(s, format, ap); va_end(ap); } m_len += lstrlen(s); if(m_len < m_size) ::lstrcat(m_data,s); else { LPTSTR temp = m_data; //Del(m_data); if(m_len < RSTR_STEP) m_size = RSTR_STEP; else if(m_len < RSTR_MAX) m_size = RSTR_MAX; else m_size = m_len + sizeof(TCHAR); m_data = (LPTSTR)New(m_size * sizeof(TCHAR)); if(m_data) exwsprintf(m_data,"%s%s\0",temp,s); else init(); Del(temp); } return m_len; } ////////////////////////////////////////////////// // //设置m_data长度 // bClear:清除数据标志 // =FALSE:不清除,如果原有m_data长度大于size,不缩减m_data长度, // 截断已有数据到size长度 // =TRUE:清除已有数据 // // ////////////////////////////////////////////////// DWORD ringStr::SetLength(DWORD size,BOOL bClear/*=FALSE*/) { if(m_data) { LPTSTR temp; if(size > m_size) { temp = m_data; m_data = (LPTSTR)New(size * sizeof(TCHAR)); if(m_data) { m_size = size; if(!bClear) lstrcpy(m_data,temp); else m_len = 0; Del(temp); } else m_data = temp; } else { if(bClear) Clear(); else memset(m_data + size,0,(m_size - size)*sizeof(TCHAR)); } } else { m_data = (LPTSTR)New(size * sizeof(TCHAR)); if(m_data) { m_size = size; m_len = 0; } else init(); } return m_size; } void ringStr::resizeBuf(LPCTSTR str) { if(str) { DWORD len = (DWORD)lstrlen(str); if(len < m_size) { Clear(); lstrcpy(m_data,str); m_len = len; } else { LPTSTR temp = m_data; m_data = (LPTSTR)New((len + 1) * sizeof(TCHAR)); if(m_data) { m_len = len; m_size = len + 1; lstrcpy(m_data,str); Del(temp); } else m_data = temp; } } else Clear(); } //ANSI与UNICODE通用版本,参数类型根据版本为LPCSTR或LPCWSTR const ringStr& ringStr::operator=(LPCTSTR str) { if(str != m_data) resizeBuf(str); return *this; } const ringStr& ringStr::operator=(const ringStr& str) { if(this == &str) return *this; return operator=(str.m_data); } const ringStr& ringStr::operator=(const int number) { if(!m_data) init(); else if(m_size < RSTR_INIT) SetLength(RSTR_INIT,TRUE); wsprintf(m_data,"%d\0\0",number); m_len = lstrlen(m_data); return *this; } #ifndef _UNICODE //ANSI版本专用 const ringStr& ringStr::operator=(LPCWSTR str) { if(str) { int z = WideCharToMultiByte(CP_ACP,WC_SEPCHARS|WC_COMPOSITECHECK,(LPWSTR)str,-1,NULL,0,NULL,NULL); SetLength(z+1,TRUE); WideCharToMultiByte(CP_ACP,WC_SEPCHARS|WC_COMPOSITECHECK,(LPWSTR)str,-1,m_data,z,NULL,NULL); GetLength(); } return *this; } #endif const ringStr& ringStr::operator=(TCHAR ch) { TCHAR s[2] = {ch,'\0'}; resizeBuf(s); return *this; } const ringStr& ringStr::operator=(const unsigned char* psz) { *this = (LPCSTR)psz; return *this; } const ringStr& ringStr::operator+=(const int number) { TCHAR s[16]; wsprintf(s,"%d\0\0",number); return operator+=(s); } const ringStr& ringStr::operator+=(LPCTSTR s) { if(!s) return *this; m_len += lstrlen(s); if(m_len < m_size) ::lstrcat(m_data,s); else { if(m_len < RSTR_STEP) m_size = RSTR_STEP; else if(m_len < RSTR_MAX) m_size = RSTR_MAX; else m_size = m_len + sizeof(TCHAR); LPTSTR temp = (LPSTR)New(m_size); if(m_data == NULL) lstrcpy(temp,s); else exwsprintf(temp,"%s%s\0",m_data,s); Del(m_data); m_data = temp; } return *this; } const ringStr& ringStr::operator+=(const ringStr& str) { return operator+=(str.m_data); } const ringStr& ringStr::operator+=(TCHAR ch) { TCHAR s[2] = {ch,'\0'}; return operator+=(s); } BOOL ringStr::operator ==(const ringStr& str) const { if(str.m_data && m_data) return !lstrcmp(m_data,str.m_data); else return (!str.m_data && !m_data); } BOOL ringStr::operator ==(LPCTSTR str) const { if(m_data && str) return !lstrcmp(m_data,str); else return (!m_data && !str); } BOOL ringStr::operator !=(const ringStr& str) const { if(str.m_data && m_data) return lstrcmp(m_data,str.m_data); else return (str.m_data || m_data); } BOOL ringStr::operator !=(LPCTSTR str) const { if(m_data && str) return lstrcmp(m_data,str); else return (m_data || str); } BOOL ringStr::operator <(const ringStr& str) const { if(str.m_data && m_data) return (lstrcmp(m_data,str.m_data) < 0); else return (BOOL)(str.m_data); } BOOL ringStr::operator >(const ringStr& str) const { if(str.m_data && m_data) return (lstrcmp(m_data,str.m_data) > 0); else return (BOOL)(m_data); } BOOL ringStr::operator <=(const ringStr& str) const { return !operator > (str); } BOOL ringStr::operator >=(const ringStr& str) const { return !operator < (str); } ringStr ringStr::operator +(const ringStr& rhs) const { ringStr temp = *this; temp += rhs.m_data; return temp; } ringStr ringStr::operator +(TCHAR ch) const { ringStr temp = *this; temp += ch; return temp; } int ringStr::cmp(const ringStr& str) const { if(str.m_data && m_data) return lstrcmp(m_data,str.m_data); else if(m_data) return -1; else if(str.m_data) return 1; else return 0; } int ringStr::cmpi(const ringStr& str) const { if(str.m_data && m_data) return lstrcmpi(m_data,str.m_data); else if(m_data) return -1; else if(str.m_data) return 1; else return 0; } ringStr ringStr::replace(LPCTSTR str1,LPCTSTR str2,BOOL bAll/* = TRUE*/) const { ringStr temp; replace(temp,str1,str2,bAll); return temp; } BOOL ringStr::replace(ringStr& temp,LPCTSTR str1,LPCTSTR str2,BOOL bAll/* = TRUE*/) const { if(str1 == NULL || str2 == NULL || m_data == NULL || m_len == 0) { temp = m_data; return FALSE; } int l1 = lstrlen(str1); int l2 = lstrlen(str2); int addstep = l2 - l1; //如果替换后字串超长,需增加的字串长度 int i,pos = 0; LPTSTR dest,src; pos = indexOf(str1,pos); src = m_data; if(addstep <= 0) temp.SetLength(m_size,TRUE); else temp.SetLength(m_size + (bAll?count(str1):1) * addstep + 1,TRUE); dest = temp.m_data; if(bAll) { i = 0; while(pos >= 0) { //COPY 匹配字串前面的字符 lstrcpyn(dest,src,pos - i + 1); dest += pos - i; src += pos - i; //替换 str1 为 str2 lstrcpyn(dest,str2,l2 + 1); dest += l2; src += l1; i = pos + l1; //寻求下一次匹配 pos = indexOf(str1,i); } } else { if(pos >= 0) { //COPY 匹配字串前面的字符 lstrcpyn(dest,src,pos + 1); dest += pos; src += pos; //替换 str1 为 str2 lstrcpyn(dest,str2,l2 + 1); dest += l2; src += l1; } } //补齐后续字串 lstrcpyn(dest,src,m_len - (src - m_data) + 1); temp.GetLength(); return TRUE; } void ringStr::replace(TCHAR c1,TCHAR c2,BOOL bAll/* = TRUE*/) { LPTSTR tmp = m_data; if(tmp) if(bAll) for(DWORD i=0;i<m_len;i++) { if(*tmp == c1) *tmp = c2; tmp ++; } else for(DWORD i=0;i<m_len;i++) { if(*tmp == c1) { *tmp = c2; return; } tmp ++; } } ringStr ringStr::SubString(int start,int count/* = 0*/) const { ringStr temp; if(start < 0) start = 0; if(count <= 0 || (DWORD)(count + start) >= m_len) count = m_len - start; if(count <= 0) //如果start超出范围,m_len - start有可能 <0 return temp; temp.SetLength(count + sizeof(TCHAR)); LPTSTR src = m_data + start; LPTSTR dest = temp.m_data; lstrcpyn(dest,src,count + 1); temp.GetLength(); return temp; } ringStr ringStr::SubString(LPCTSTR szStart,LPCTSTR szEnd,int nStart/*=0*/,int* nIndex/*=NULL*/) const { int lens=0,s,e=0,sp; if(szStart) lens = lstrlen(szStart); s = indexOf(szStart,nStart); if(s < 0) sp = nStart; else sp = s + lens; if(szEnd) e = indexOf(szEnd,sp); if(e < 0) e = m_len; //if(e == 0 || (s == 0 && szStart) || (e - s - lens == 0))//严格判断版本 if((s < 0 && szStart) || (e - s - lens == 0)) //szEnd找不到返回到结尾 { //未找到szStart或szEnd,e只有szEnd有效且找不到才为0 if(nIndex) *nIndex = e; return (LPTSTR)NULL; } else //找到匹配的字串 { if(nIndex) *nIndex = e; return SubString(s + lens,e - s - lens); } } /********************************************************* // //搜索字符串 // //参数: // str:要搜索的字符串 // start:搜索起始位置,<0:从头开始,>=0:从start位置开始搜索 // ntimes:第ntimes匹配(从1开始计数) // //返回:-1:未找到,否则>=0 // //*******************************************************/ int ringStr::indexOf(LPCTSTR str,int start/*=-1*/,int ntimes/*=1*/) const { if(!str || *str == '\0' || m_data == NULL || *m_data == '\0' || start > (int)m_len) return -1; if(start < 0) start = 0; LPTSTR lpszCur = m_data + start; int nCnt = 1,nLen = lstrlen(str); //修正:原始版本,工程默认定义_MBCS,_tcsstr的_MBCS版本狂慢! //while((lpszCur - m_data) < (int)m_len && ((lpszCur = _tcsstr(lpszCur,str)) != NULL)) #ifndef _UNICODE while((lpszCur - m_data) < (int)m_len && ((lpszCur = strstr(lpszCur,str)) != NULL)) #else while((lpszCur - m_data) < (int)m_len && ((lpszCur = wcsstr(lpszCur,str)) != NULL)) #endif { if(++nCnt > ntimes) return lpszCur - m_data; else lpszCur += nLen; } return -1; } //ntimes:第ntimes匹配(从1开始计数) int ringStr::lastIndexOf(LPCTSTR str,int ntimes/*=1*/) const { if(!str || *str == '\0' || m_data == NULL || *m_data == '\0') return -1; int nLenF = lstrlen(str); if(nLenF > (int)m_len) return -1; LPTSTR lpszEndF = (LPTSTR)str + nLenF -1; LPTSTR pS = m_data + m_len - nLenF; LPTSTR pFind; LPTSTR p; int cnt = 1; //匹配不成功,被查询串指针将向左移动的字符数 int nMove; while(pS >= m_data) { pFind = (LPTSTR)str; while(pFind <= lpszEndF) { if(*pS != *pFind) { //被查询串的当前字符是否在查询串当前字符后面的字串里? if(pFind == lpszEndF) nMove = nLenF; else { p = pFind + 1; while(p <= lpszEndF) { if(*p == *pS) { nMove = p - str; break; } p ++; } if(p > lpszEndF) nMove = nLenF; } break; } pFind ++; pS ++; } if(pFind > lpszEndF) { cnt ++; if(cnt > ntimes) return((pS - m_data) - nLenF); else nMove = nLenF << 1; } pS -= nMove; } return -1; } //计算含有多少str子串 int ringStr::count(LPCTSTR str) const { if(!str || *str == '\0' || m_data == NULL || *m_data == '\0') return 0; int nCnt = 0,nLen = lstrlen(str); LPTSTR lpszCur = m_data; //修正:原始版本,工程默认定义_MBCS,_tcsstr的_MBCS版本狂慢! //while((lpszCur - m_data) < (int)m_len && ((lpszCur = _tcsstr(lpszCur,str)) != NULL)) #ifndef _UNICODE while((lpszCur - m_data) < (int)m_len && ((lpszCur = strstr(lpszCur,str)) != NULL)) #else while((lpszCur - m_data) < (int)m_len && ((lpszCur = wcsstr(lpszCur,str)) != NULL)) #endif { nCnt ++; lpszCur += nLen; } return nCnt; } ringStr ringStr::Insert(const ringStr& str, int index) { ringStr temp; int i,cnt = str.len(); LPTSTR src,dest; if(cnt == 0 || isClear()) { temp = *this; return temp; } if((cnt + m_len) > m_size) temp.SetLength(cnt + m_len + sizeof(TCHAR),TRUE); else temp.SetLength(m_size,TRUE); src = m_data; dest = temp.m_data; for(i=0;i<index;i++) *dest++ = *src++; for(i=0;i<cnt;i++) *dest++ = str.m_data[i]; cnt = m_len - index; for(i=0;i<cnt;i++) *dest++ = *src++; return temp; } ringStr ringStr::Delete(int index, int count) { ringStr temp = *this; LPTSTR src,dest; int i; if(isClear()) return temp; src = m_data; dest = temp.m_data; if(index > (int)m_len) index = m_len; for(i=0;i<index;i++) *dest++ = *src++; if((index + count) > (int)m_len) count = m_len - index; src += count; for(i=index+count;i<(int)m_len;i++) *dest++ = *src++; return temp; } void ringStr::toLower() { if(m_data && m_len > 0) { LPTSTR tmp = m_data + m_len - 1; while(tmp >= m_data) { *tmp = (char)tolower(*tmp); tmp --; } } } void ringStr::toUpper() { if(m_data && m_len > 0) { LPTSTR tmp = m_data + m_len - 1; while(tmp >= m_data) { *tmp = (char)toupper(*tmp); tmp --; } } } void ringStr::Trim() { RTrim(); LTrim(); } void ringStr::LTrim() { LPTSTR start = m_data,tmp = m_data,end = m_data + m_len - 1; while(start <= end) { if(*start == ' ') { start ++; m_len --; } else break; } if(start > m_data) { while(start <= end) { *tmp++ = *start++; } memset(tmp,0,(end - (tmp - 1)) * sizeof(TCHAR)); } } void ringStr::RTrim() { LPTSTR tmp = m_data + m_len - 1; while(tmp >= m_data) { if(*tmp == ' ') { *tmp-- = 0; m_len --; } else break; } } WCHAR* ringStr::wstring(int* nLen) { int len = (m_len << 1) + 2; if(m_wData) Del(m_wData); m_wData = (WCHAR*)New(len * sizeof(WCHAR)); if(m_wData && m_data) { len = MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,m_data,-1,m_wData,len); if(nLen) *nLen = len; return m_wData; } return L""; } ringStr operator +(LPTSTR lhs, const ringStr& rhs) { ringStr temp(lhs); temp += rhs.string(); return temp; } //添加count个c字符到串尾 void ringStr::Append(TCHAR c,int count) { LPTSTR s = (LPTSTR)New((count+1) * sizeof(TCHAR)); LPTSTR p = s; if(s) { for(int i=0;i<count;i++) *p++ = c; operator+=(s); } Del(s); } //添加lpstr和若干个c字符到串尾,总添加字符数为count //如果lpstr长度大于count,截断lpstr为count个字符 void ringStr::AppendSize(LPCTSTR lpstr,TCHAR c,int count) { if(count <= 0) return; int n = lstrlen(lpstr); LPTSTR p,s = (LPTSTR)New((count+2) * sizeof(TCHAR)); if(s) { if(lpstr) lstrcpyn(s,lpstr,count+1); //+1:最后的'\0' p = s + lstrlen(s); for(int i=p-s;i<count;i++) *p++ = c; operator+=(s); } Del(s); } /***********废弃代码,但有参考价值,字符串搜索算法*********************** //ntimes:第ntimes匹配(从1开始计数) //返回:-1:未找到,否则>=0 int ringStr::indexOf(LPCTSTR str,int start,int ntimes) const { if(!str || m_len < 1) return -1; if(start < 0) start = 0; int nLenF = lstrlen(str); if(nLenF < 1) return -1; LPTSTR lpszEndF = (LPSTR)str + nLenF -1; LPTSTR lpszEndS = m_data + m_len -1; LPSTR pS = m_data + start + nLenF -1; LPSTR pFind; LPSTR p; //匹配不成功,被查询串指针将向右移动的字符数 int nMove; int cnt = 1; BOOL bEnd = FALSE; while(pS <= lpszEndS) { //从右向左匹配。 pFind = lpszEndF; //比较被查询串的当前字符是否和查询串的最右边字 //符匹配,如果匹配则回溯比较 if(pS == lpszEndS) bEnd = TRUE; while(pFind >= str) { if(*pS != *pFind) { //被查询串的当前字符是否在查询串当前字符前面的字串里? if(pFind == str) nMove = nLenF; else { p = pFind - 1; while(p >= str) { if(*p == *pS) { nMove = lpszEndF - p; break; } p --; } if(p < str) nMove = nLenF; } break; } // 匹配成功一个,向左回溯 pFind --; pS --; } if(pFind < str) { cnt ++; if(cnt > ntimes) return((pS - m_data) + 2); else nMove = nLenF << 1; } if(bEnd) return 0; pS += nMove; } return 0; } **********************************************************/